﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms; using Montana.Entidades;
using Montana.Reportes;

namespace Montana
{
    public partial class frmFactura : Form
    {
        bool cambioPrecio = false;

        public frmFactura()
        {
            InitializeComponent();
        }

        static frmFactura instancia;
        public static frmFactura Instancia
        {
            get
            {
                if (instancia == null)
                    instancia = new frmFactura();

                return instancia;
            }
            set
            {
                instancia = value;
            }
        }

        private void frmFactura_Load(object sender, EventArgs e)
        {
            CrearColumnas();

            CrearColumnasCheque();

            CrearColumnasResago();

            Cliente cli = new Cliente();
            cli.CargarCombo(cboCliente, true);

            Producto prod = new Producto();
            prod.CargarCombo(cboProducto, true);

            Factura fac = new Factura();
            txtNumeroFactura.Text = fac.ObtenerUltimoNumero();

            txtFechaFactura.Text = DateTime.Now.ToShortDateString();

            Instancia = this;
        }

        private void CrearColumnasResago()
        {
            lswResago.Columns.Add("Descripción", 100);
            lswResago.Columns.Add("Kilos", 60, HorizontalAlignment.Right);
            lswResago.Columns.Add("Precio X Kilo", 90, HorizontalAlignment.Right);
            lswResago.Columns.Add("Subtotal", 70, HorizontalAlignment.Right);
            lswResago.Columns.Add("Contable", 80);
        }

        private void CrearColumnasCheque()
        {
            lswCheque.Columns.Add("Banco", 100);
            lswCheque.Columns.Add("Número", 100);
            lswCheque.Columns.Add("Fecha Dep.", 80);
            lswCheque.Columns.Add("Importe", 90, HorizontalAlignment.Right);
            lswCheque.Columns.Add("Contable", 80);
        }

        private void CrearColumnas()
        {
            lswProducto.Columns.Add("Cantidad", 70); //item raiz
            lswProducto.Columns.Add("Código", 70, HorizontalAlignment.Right); //1
            lswProducto.Columns.Add("Producto", 250); //2

            lswProducto.Columns.Add("Peso U.", 90, HorizontalAlignment.Right); //3
            lswProducto.Columns.Add("Precio U.", 90, HorizontalAlignment.Right); //4

            lswProducto.Columns.Add("Peso total", 100, HorizontalAlignment.Right); //5
            lswProducto.Columns.Add("Precio total", 100, HorizontalAlignment.Right); //6            

            lswProducto.Columns.Add("Mano de Obra", 100); //7
            lswProducto.Columns.Add("Dato contable", 100); //8
            lswProducto.Columns.Add("Suma resagos", 105); //9
        }

        private void btnCerrar_Click(object sender, EventArgs e)
        {
            DialogResult res = Validacion.MostrarMensaje("Los datos no guardados se perderán. ¿Desea continuar?", TipoMensaje.Pregunta);
            if (res == DialogResult.No)
                return;

            this.Close();
        }

        private void frmFactura_KeyDown(object sender, KeyEventArgs e)
        {
            switch (e.KeyCode)
            {
                case Keys.Escape:
                    btnCerrar_Click(this, null);
                    break;
                case Keys.F3:
                    btnBuscarFactura_Click(this, null);
                    break;
                case Keys.F1:                    
                    break;
                case Keys.F5:
                    txtCodigoProducto.Focus();
                    break;
                case Keys.F6:
                    CambiarPrecioPorDefecto();
                    break;
                case Keys.F7:
                    txtPorcentajeBonificacion.Focus();
                    break;
                case Keys.F9:
                    txtEfectivoEntregado.Focus();
                    break;
                case Keys.F10:
                    txtBanco.Focus();
                    break;
                case Keys.F11:
                    txtDescripcionResago.Focus();
                    break;
                case Keys.F2:
                    btnImprimir_Click(this, null);
                    break;
            }
        }

        private void CambiarPrecioPorDefecto()
        {
            if (lblLabelPrecio.ForeColor == Color.Red)
            {
                lblLabelPrecio.Text = "Precio (F6)";                
                lblLabelPrecio.ForeColor = Color.Black;
                lblLabelPrecio.Font = new Font(lblLabelPrecio.Font, FontStyle.Regular);

                lblPrecioManoObra.Text = "Precio mano/obra";
                lblPrecioManoObra.ForeColor = Color.Red;                
                lblPrecioManoObra.Font = new Font(lblPrecioManoObra.Font, FontStyle.Bold);                                                
            }
            else
            {
                lblLabelPrecio.Text = "Precio";
                lblLabelPrecio.ForeColor = Color.Red;
                lblLabelPrecio.Font = new Font(lblLabelPrecio.Font, FontStyle.Bold);

                lblPrecioManoObra.Text = "Precio mano/obra (F6)";
                lblPrecioManoObra.ForeColor = Color.Black;
                lblPrecioManoObra.Font = new Font(lblPrecioManoObra.Font, FontStyle.Regular);  
            }
        }

        private void btnImprimir_Click(object sender, EventArgs e)
        {
            if (!btnImprimir.Enabled)
                return;

            if (this.Tag.ToString() != "")
                ImprimirRemito((int)this.Tag);
        }

        private void ImprimirRemito(int idFactura)
        {
            frmImprimirRemito frm = new frmImprimirRemito();

            frm.IDFactura = idFactura;

            frm.ShowDialog();

            frmReporte.Instancia.BringToFront();
        }

        private void cboCliente_SelectedIndexChanged(object sender, EventArgs e)
        {
            LimpiarEncabezado();

            if (cboCliente.Text == "")               
                return;

            Cliente cli = new Cliente();
            cli = cli.BuscarPorID((int)cboCliente.SelectedValue);
            
            CargarEncabezado(cli);
            
            btnImprimir.Enabled = false;
        }

        private void CargarEncabezado(Cliente cli)
        {
            txtCodigoCliente.Tag = cli;

            txtCodigoCliente.Text = cli.Codigo;
            txtCUIT.Text = cli.CUIT;
            txtTelefono.Text = cli.Telefono;
            txtDireccion.Text = cli.Direccion;
            txtProvincia.Text = cli.Provincia;
            txtLocalidad.Text = cli.Localidad;
            txtLetra.Text = cli.LetraFactura;
            txtCondicionIVA.Text = cli.Condicioniva;

            txtSaldoAnterior.Text = ObtenerSaldo(cli.ID, cli.Saldo);
            txtSaldoAnterior2.Text = ObtenerSaldo2(cli.ID, cli.Saldo2);
            //txtSaldoAnterior.Text = cli.SaldoFormato;

            txtSaldoAnteriorKg.Text = cli.Saldokg.ToString("0.00");
            txtPorcentajeBonificacion.Text = cli.Bonificacion.ToString("0.00");
            txtTipoCliente.Text = cli.Tipocliente;

            if (cli.IVADiscriminado == "N")
                MostrarTextIVA(false);

            if (cli.IVADiscriminado == "S")
                MostrarTextIVA(true);

            txtCodigoProducto.Text = "";
            cboProducto.SelectedIndex = 0;
            txtPrecio.Text = "";
            txtPrecioManoObra.Text = "";
            txtCantidad.Text = "";

            txtSubtotal.Text = "";
            txtTotalFactura.Text = "";
            txtNuevoSaldo.Text = "";
            txtNuevoSaldo2.Text = "";

            txtPrecioResago.Text = cli.Precioresago.ToString("0.00");

            lswProducto.Items.Clear();
        }

        private string ObtenerSaldo(int idCliente, decimal saldoInicial)
        {
            Factura fac = new Factura();
            List<Factura> facturas = fac.BuscarPendientesBlanco(idCliente);

            foreach (Factura f in facturas)
            {
                decimal importeTotal = f.Importetotal - (f.Importetotal * f.Porcentajebonificacion / 100);
                importeTotal += f.Importeiva;

                saldoInicial += importeTotal - f.Importecancelado;
            }

            return saldoInicial.ToString("0.00");
        }

        private string ObtenerSaldo2(int idCliente, decimal saldoInicial)
        {
            Factura fac = new Factura();
            List<Factura> facturas = fac.BuscarPendientesNegro(idCliente);

            foreach (Factura f in facturas)
            {
                decimal importeTotal = f.Importetotal - (f.Importetotal * f.Porcentajebonificacion / 100);
                //importeTotal += f.Importeiva;

                saldoInicial += importeTotal - f.Importecancelado;
            }

            return saldoInicial.ToString("0.00");
        }

        private void MostrarTextIVA(bool mostrar)
        {
            txtImporteIVA.Visible = mostrar;
            txtPorcentajeIVA.Visible = mostrar;
            lblLabelIVA.Visible = mostrar;
        }

        private void txtCodigoCliente_TextChanged(object sender, EventArgs e)
        {

        }

        private void LimpiarEncabezado()
        {
            txtCodigoCliente.Tag = "";
            txtCodigoCliente.Text = "";
            
            txtCUIT.Text = "";
            txtTelefono.Text = "";
            txtDireccion.Text = "";
            txtProvincia.Text = "";
            txtLocalidad.Text = "";
            
            txtPrecioResago.Text = "";
            txtTipoCliente.Text = "";
            txtCondicionIVA.Text = "";
            txtPorcentajeIVA.Text = "";

            txtSaldoAnterior.Text = "";

            txtPorcentajeBonificacion.Text = "";

            txtResagosProductos.Text = "";
            txtMermaKilos.Text = "";
            txtMermaPorcentaje.Text = "";
            txtSaldoAnteriorKg.Text = "";
            txtTotalResagos.Text = "";
            txtTotalKilosEntregado.Text = "";
            txtNuevoSaldoKg.Text = "";
                     
        }
       
        private void btnAgregarProducto_Click(object sender, EventArgs e)
        {
            //marca si el producto se va a facturar o no
            DialogResult res = Validacion.MostrarMensaje("¿Es dato contable?", TipoMensaje.Pregunta);
            string datoContable = res == DialogResult.Yes ? "S" : "N";

            if (!ValidarProducto(datoContable))
                return;

            string sumarSaldoResagos = "N";

            //vuelve a cargar los precios (esto es porque si es un dato No Contable, a los precios se saca el IVA)
            CargarPrecios(datoContable == "S");

            string precioAux = "";
            string esPrecioManoObra = "";
            if (lblLabelPrecio.ForeColor == Color.Red)
            {
                precioAux = txtPrecio.Text;
                esPrecioManoObra = "N";
            }
            else
            {
                precioAux = txtPrecioManoObra.Text;
                esPrecioManoObra = "S";

                res = Validacion.MostrarMensaje("¿Sumar los kilos al saldo de resagos?", TipoMensaje.Pregunta);
                sumarSaldoResagos = res == DialogResult.Yes ? "S" : "N";
            }
            
            decimal cant = Validacion.ValDecimal(txtCantidad);
            decimal precio = decimal.Parse(precioAux);
            decimal subTotal = cant * precio;
            decimal peso = 0;
            decimal cantidad = Validacion.ValDecimal(txtCantidad);

            if (txtPesoUnitario.Text != "")
                peso = decimal.Parse(txtPesoUnitario.Text);

            AgregarProducto(txtCodigoProducto.Text, (int)cboProducto.SelectedValue, 
                    cboProducto.Text, cantidad, esPrecioManoObra, precio, subTotal, datoContable, peso, sumarSaldoResagos);

            txtCodigoProducto.Focus();

            CalcularTotales();
        }

        private void AgregarProducto(string codigoProducto, int idProducto, string producto, decimal cantidad, string esPrecioManoObra, decimal precio, decimal subTotal, string datoContable, decimal peso, string sumarSaldoResagos)
        {
            lswProducto.Items.Add(cantidad.ToString());
            lswProducto.Items[lswProducto.Items.Count - 1].Tag = idProducto;
            lswProducto.Items[lswProducto.Items.Count - 1].SubItems.Add(codigoProducto); //1
            lswProducto.Items[lswProducto.Items.Count - 1].SubItems.Add(producto); //2

            lswProducto.Items[lswProducto.Items.Count - 1].SubItems.Add(peso.ToString("0.00")); //3
            lswProducto.Items[lswProducto.Items.Count - 1].SubItems.Add(precio.ToString("0.00")); //4

            decimal pesoTotal = peso * cantidad;
            lswProducto.Items[lswProducto.Items.Count - 1].SubItems.Add(pesoTotal.ToString("0.00")); //5
            lswProducto.Items[lswProducto.Items.Count - 1].SubItems.Add(subTotal.ToString("0.00")); //6

            lswProducto.Items[lswProducto.Items.Count - 1].SubItems.Add(esPrecioManoObra == "S" ? "Si" : "No"); //7
            lswProducto.Items[lswProducto.Items.Count - 1].SubItems.Add(datoContable == "S" ? "Si" : "No"); //8

            lswProducto.Items[lswProducto.Items.Count - 1].SubItems.Add(sumarSaldoResagos == "S" ? "Si" : "No"); //8
        }

        private void CalcularTotales()
        {
            decimal subtotal = 0;
            decimal subtotalNoContable = 0;
            decimal subtotalContable = 0;

            decimal totalKilosProductos = 0;

            decimal boni = 0;
            decimal boniBlanco = 0; //para sacar el IVA, solo se usa la bonificacion de los productos en blanco
            decimal iva = 0;
            decimal total = 0;

            bool hayProductosManoObra = false;

            //suma el importe de los items
            foreach (ListViewItem item in lswProducto.Items)
            {
                if (item.SubItems[8].Text == "Si")
                    subtotalContable += Validacion.ValDecimal(item.SubItems[6].Text);
                else
                    subtotalNoContable += Validacion.ValDecimal(item.SubItems[6].Text);

                if (item.SubItems[9].Text == "Si")
                {
                    totalKilosProductos += Validacion.ValDecimal(item.SubItems[5].Text);
                    hayProductosManoObra = true;
                }
            }
            subtotal = subtotalContable + subtotalNoContable;
            txtResagosProductos.Text = totalKilosProductos.ToString("0.00");

            //bonificacion
            if (txtPorcentajeBonificacion.Text.Trim() != "")
            {
                boni = subtotal * Validacion.ValDecimal(txtPorcentajeBonificacion) / 100;
                boniBlanco = subtotalContable * Validacion.ValDecimal(txtPorcentajeBonificacion) / 100;
            }

            txtImporteBonificacion.Text = boni.ToString("0.00");

            //decimal total2 = subtotalNoContable - Validacion.ValDecimal(txtImporteBonificacion);
            //txtTotal2.Text = total2.ToString("0.00");

            //IVA
            Cliente cli = txtCodigoCliente.Tag as Cliente;
            
            if (cli != null && cli.IVADiscriminado == "S")
            {
                decimal porIVA = cli.Porcentajeiva; 
                txtPorcentajeIVA.Text = porIVA.ToString("0.00");

                if (subtotalContable != 0)
                    iva = (subtotalContable - boniBlanco) * (porIVA / 100);
                else
                    iva = 0;

                txtImporteIVA.Text = iva.ToString("0.00");

                total += (subtotalContable - boniBlanco) + iva;

                total += subtotalNoContable;
            }
            else
                total = subtotal - boni;

            //subtotal
            txtSubtotal.Text = subtotal.ToString("0.00");

            //total
            //txtTotalFactura.Text = total.ToString("0.00");
            total = Validacion.ValDecimal(txtSubtotal) - Validacion.ValDecimal(txtImporteBonificacion) + Validacion.ValDecimal(txtImporteIVA);
            txtTotalFactura.Text = total.ToString("0.00");


            //suma cheques
            decimal totalCheques = 0;
            foreach (ListViewItem item in lswCheque.Items)
                totalCheques += Validacion.ValDecimal(item.SubItems[3].Text);

            //suma resagos
            decimal totalImporteResagos = 0;
            decimal totalKilosResagos = 0;
            foreach (ListViewItem item in lswResago.Items)
            {
                totalImporteResagos += Validacion.ValDecimal(item.SubItems[3].Text);
                totalKilosResagos += Validacion.ValDecimal(item.SubItems[1].Text);
            }

            if (hayProductosManoObra)
            {
                txtTotalKilosEntregado.Text = totalKilosResagos.ToString("0.00");
                decimal merma = totalKilosProductos * Validacion.ValDecimal(txtMermaPorcentaje) / 100;  // 130 kg. x 10 / 100
                txtMermaKilos.Text = merma.ToString("0.00");
            }
            else
            {
                txtTotalKilosEntregado.Text = "0,00";
                txtMermaKilos.Text = "0,00";
                txtMermaPorcentaje.Text = "0,00";
            }

            decimal totalKilos = Validacion.ValDecimal(txtResagosProductos) + Validacion.ValDecimal(txtMermaKilos) + Validacion.ValDecimal(txtSaldoAnteriorKg);
            txtTotalResagos.Text = totalKilos.ToString("0.00");

            decimal nuevoSaldoKg = totalKilos - Validacion.ValDecimal(txtTotalKilosEntregado);
            txtNuevoSaldoKg.Text = nuevoSaldoKg.ToString("0.00");

            //saca el SALDO
            decimal nuevoSaldo = total - 
                Validacion.ValDecimal(txtEfectivoEntregado) - 
                totalCheques - totalImporteResagos + Validacion.ValDecimal(txtSaldoAnterior);

            txtNuevoSaldo.Text = nuevoSaldo.ToString("0.00");

            //saca el SALDO 2
            decimal nuevoSaldo2 = total -
                Validacion.ValDecimal(txtEfectivoEntregado) -
                totalCheques - totalImporteResagos + Validacion.ValDecimal(txtSaldoAnterior2);

            txtNuevoSaldo2.Text = nuevoSaldo2.ToString("0.00");
        }

        private bool ValidarProducto(string datoContable)
        {
            if (Validacion.EstaVacio(txtCodigoProducto, "Debe ingresar el código del producto"))
                return false;

            if (Validacion.EstaVacio(cboProducto, "Debe ingresar el producto"))
                return false;

            if (Validacion.EstaVacio(txtPrecio, "Debe ingresar el precio"))
                return false;

            if (Validacion.EstaVacio(txtCantidad, "Debe ingresar la cantidad"))
                return false;

            return true;
        }

        private void btnQuitarProducto_Click(object sender, EventArgs e)
        {
            if (lswProducto.SelectedItems.Count == 0)
                return;

            lswProducto.SelectedItems[0].Remove();

            CalcularTotales();
        }

        private void txtPorcentajeBonificacion_TextChanged(object sender, EventArgs e)
        {
            CalcularTotales();
        }

        private void btnAgregarCheque_Click(object sender, EventArgs e)
        {
            if (!ValidarCheque())
                return;

            decimal importe = Validacion.ValDecimal(txtImporteCheque);

            AgregarCheque(txtBanco.Text, txtNumeroCheque.Text, txtFechaDeposito.Text, importe, chkChequeEsContable.Checked);

            txtBanco.Focus();

            CalcularTotales();
        }

        private void AgregarCheque(string banco, string numeroCheque, string fechaDeposito, decimal importe, bool esContable)
        {
            lswCheque.Items.Add(banco);
            lswCheque.Items[lswCheque.Items.Count - 1].SubItems.Add(numeroCheque);
            lswCheque.Items[lswCheque.Items.Count - 1].SubItems.Add(fechaDeposito);
            lswCheque.Items[lswCheque.Items.Count - 1].SubItems.Add(importe.ToString("0.00"));
            lswCheque.Items[lswCheque.Items.Count - 1].SubItems.Add(esContable ? "Si" : "No");
        }

        private bool ValidarCheque()
        {
            if (Validacion.EstaVacio(txtBanco, "Debe ingresar el banco"))
                return false;

            if (Validacion.EstaVacio(txtNumeroCheque, "Debe ingresar el número"))
                return false;

            if (Validacion.EstaVacio(txtFechaDeposito, "Debe ingresar la fecha"))
                return false;

            if (Validacion.ValFecha(txtFechaDeposito, "La fecha es incorrecta"))
                return false;

            return true;
        }

        private void btnQuitarCheque_Click(object sender, EventArgs e)
        {
            if (lswCheque.SelectedItems.Count == 0)
                return;

            lswCheque.SelectedItems[0].Remove();

            CalcularTotales();
        }

        private void btnAgregarResago_Click(object sender, EventArgs e)
        {
            if (!ValidarResago())
                return;

            decimal precio = Validacion.ValDecimal(txtPrecioResago);
            decimal kilos = Validacion.ValDecimal(txtKilosResagos);
            decimal subtotal = precio * kilos;

            AgregarResago(txtDescripcionResago.Text, kilos, precio, subtotal, chkResagoEsContable.Checked);

            txtDescripcionResago.Focus();

            CalcularTotales();
        }

        private void AgregarResago(string descripcion, decimal kilos, decimal precio, decimal subtotal, bool esContable)
        {
            lswResago.Items.Add(descripcion);
            lswResago.Items[lswResago.Items.Count - 1].SubItems.Add(kilos.ToString("0.00"));
            lswResago.Items[lswResago.Items.Count - 1].SubItems.Add(precio.ToString("0.00"));
            lswResago.Items[lswResago.Items.Count - 1].SubItems.Add(subtotal.ToString("0.00"));
            lswResago.Items[lswResago.Items.Count - 1].SubItems.Add(esContable ? "Si" : "No");
        }

        private bool ValidarResago()
        {
            if (Validacion.EstaVacio(txtDescripcionResago, "Debe ingresar la descripción"))
                return false;

            if (Validacion.EstaVacio(txtKilosResagos, "Debe ingresar los kilos"))
                return false;

            if (Validacion.EstaVacio(txtPrecioResago, "Debe ingresar el precio"))
                return false;

            return true;
        }

        private void btnQuitarResago_Click(object sender, EventArgs e)
        {
            if (lswResago.SelectedItems.Count == 0)
                return;

            lswResago.SelectedItems[0].Remove();

            CalcularTotales();
        }

        private void txtEfectivoEntregado_TextChanged(object sender, EventArgs e)
        {
            CalcularTotales();
        }

        private void txtCodigoProducto_TextChanged(object sender, EventArgs e)
        {

        }

        private void txtCantidad_KeyDown(object sender, KeyEventArgs e)
        {

        }

        private void txtCodigoProducto_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == (char)13)
            {
                if (txtCodigoProducto.Text == "")
                    return;

                txtBuscarDescripcion.Text = "";

                Producto prod = new Producto();
                prod.CargarCombo(cboProducto, true);

                List<Producto> items = prod.BuscarPorCodigo(txtCodigoProducto.Text);

                if (items.Count == 0)
                    return;

                cboProducto.SelectedValue = items[0].ID.ToString();

                if (cboProducto.Text != "")
                    txtPrecio.Focus();

                e.Handled = true;
            }
        }

        private void cboProducto_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (cboProducto.Text == "")
                return;

            CargarPrecios(true);
        }

        private void CargarPrecios(bool esDatoContable)
        {
            Cliente cli = txtCodigoCliente.Tag as Cliente;
            if (cli == null)
            {
                Validacion.MostrarMensaje("Debe seleccionar un cliente");
                
                txtCodigoProducto.Text = "";
                txtPrecio.Text = "";
                txtPrecioManoObra.Text = "";
                txtCantidad.Text = "";
                cboProducto.SelectedIndex = -1;

                txtCodigoCliente.Focus();

                return;
            }

            Producto prod = new Producto();
            decimal precio, precioManoObra;

            prod = prod.BuscarPorID((int)cboProducto.SelectedValue);
            if (!cambioPrecio)
            {
                precio = prod.Preciooriginal;
                precioManoObra = prod.Preciomanoobra;
            }
            else
            {
                if (txtPrecio.Text != "")
                    precio = decimal.Parse(txtPrecio.Text);
                else
                    precio = 0;

                if (txtPrecioManoObra.Text != "")
                    precioManoObra = decimal.Parse(txtPrecioManoObra.Text);
                else
                    precioManoObra = 0;
            }

            //en caso de clientes exento, agrega el IVA unicamente si es un dato No Contable
            if (cli.IVADiscriminado == "N" && esDatoContable)
            {
                decimal porcentaje = cli.Porcentajeiva;
                precio += precio * (porcentaje / 100);
                precioManoObra += precioManoObra * (porcentaje / 100);
            }

            txtPrecio.Text = precio.ToString("0.00");
            txtPrecioManoObra.Text = precioManoObra.ToString("0.00");
            txtCodigoProducto.Text = prod.Codigo;
            txtPesoUnitario.Text = prod.Peso.ToString("0.00");

            cambioPrecio = false;
        }

        private void txtCantidad_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == (char)13)
            {
                btnAgregarProducto_Click(this, null);
                txtCodigoProducto.Focus();
                e.Handled = true;
            }
        }

        private void txtCodigoCliente_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == (char)13)
            {
                e.Handled = true;

                if (txtCodigoCliente.Text == "")
                {
                    LimpiarEncabezado();
                    return;
                }

                Cliente cli = new Cliente();

                List<Cliente> items = cli.BuscarPorCodigo(txtCodigoCliente.Text);

                if (items.Count == 0)
                {
                    LimpiarEncabezado();
                    return;
                }

                cboCliente.SelectedValue = items[0].ID.ToString();                

                txtCodigoProducto.Focus();
            }
        }

        private void btnGuardar_Click(object sender, EventArgs e)
        {
            if (!ValidarFactura())
                return;

            Factura fac = ArmarFactura();
            List<FacturaProducto> productos = ArmarProductos();
            List<Cheque> cheques = ArmarCheques();
            List<Resago> resagos = ArmarResagos();
            decimal nuevoSaldo = Validacion.ValDecimal(txtNuevoSaldo);
            decimal nuevoSaldoKg = Validacion.ValDecimal(txtNuevoSaldoKg);
            decimal saldoAnterior = Validacion.ValDecimal(txtSaldoAnterior);

            this.Tag = fac.Nueva(productos, cheques, resagos, nuevoSaldo, nuevoSaldoKg);

            Validacion.MostrarMensaje("Factura guardada");

            LimpiarEncabezado();
            LimpiarDetalle();

            txtNumeroFactura.Focus();
            btnImprimir.Enabled = true;

            DialogResult res = Validacion.MostrarMensaje("¿Desea imprimir el remito?", TipoMensaje.Pregunta);
            if (res == DialogResult.Yes)
                ImprimirRemito((int)this.Tag);
        }

        private void LimpiarDetalle()
        {
            txtCodigoProducto.Text = "";
            cboProducto.SelectedIndex = -1;
            txtPrecio.Text = "";
            txtPrecioManoObra.Text = "";
            txtCantidad.Text = "";
            lswProducto.Items.Clear();

            txtSubtotal.Text = "";
            //txtPorcentajeBonificacion.Text = "";
            txtImporteBonificacion.Text = "";
            txtPorcentajeIVA.Text = "";
            txtImporteIVA.Text = "";

            txtTotalFactura.Text = "";
            txtSaldoAnterior.Text = "";
            txtNuevoSaldo.Text = "";
            txtEfectivoEntregado.Text = "";

            txtBanco.Text = "";
            txtNumeroCheque.Text = "";
            txtFechaDeposito.Text = "";
            txtImporteCheque.Text = "";
            lswCheque.Items.Clear();

            txtDescripcionResago.Text = "";
            txtKilosResagos.Text = "";
            txtPrecioResago.Text = "";
            lswResago.Items.Clear();

            Factura fac = new Factura();
            txtNumeroFactura.Text = fac.ObtenerUltimoNumero();
        }

        private Factura ArmarFactura()
        {
            Factura f = new Factura();

            f.Nombre = txtNumeroFactura.Text;
            f.Fecha = Validacion.ValFecha(txtFechaFactura);
            f.Letra = txtLetra.Text;
            f.IDCliente = Validacion.GetValue(cboCliente);
            f.Subtotal = Validacion.ValDecimal(txtSubtotal);
            f.Porcentajebonificacion = Validacion.ValDecimal(txtPorcentajeBonificacion);
            f.Importebonificacion = Validacion.ValDecimal(txtImporteBonificacion);
            f.Porcentajeiva = Validacion.ValDecimal(txtPorcentajeIVA);
            f.Importeiva = Validacion.ValDecimal(txtImporteIVA);
            f.Importetotal = Validacion.ValDecimal(txtTotalFactura);
            f.Saldoparcial = Validacion.ValDecimal(txtNuevoSaldo);
            f.Saldoanterior = Validacion.ValDecimal(txtSaldoAnterior);
            f.Saldoanterior2 = Validacion.ValDecimal(txtSaldoAnterior2);

            f.Totalresagosproductos = Validacion.ValDecimal(txtResagosProductos);
            f.Saldofavorresagos = Validacion.ValDecimal(txtSaldoAnteriorKg);
            f.Totalresagos = Validacion.ValDecimal(txtTotalResagos);
            f.Totalresagosentregados = Validacion.ValDecimal(txtTotalKilosEntregado);
            f.Saldonuevoresagos = Validacion.ValDecimal(txtNuevoSaldoKg);

            f.Domicilioentrega = "";
            f.Numeroremito = "";

            f.Importeentregado = Validacion.ValDecimal(txtEfectivoEntregado);
            f.Efectivoescontable = chkEfectivoEsContable.Checked ? "S" : "N";

            f.Mermaporcentaje = Validacion.ValDecimal(txtMermaPorcentaje);
            f.Mermakilos = Validacion.ValDecimal(txtMermaKilos);

            decimal totalCheques = 0;
            foreach (ListViewItem item in lswCheque.Items)
                totalCheques += Validacion.ValDecimal(item.SubItems[3]);

            decimal totalResagos = 0;
            foreach (ListViewItem item in lswResago.Items)
                totalResagos = Validacion.ValDecimal(item.SubItems[1]) * Validacion.ValDecimal(item.SubItems[2]);

            f.Importecancelado = totalCheques + totalResagos + f.Importeentregado;

            return f;
        }

        private List<Resago> ArmarResagos()
        {
            List<Resago> resagos = new List<Resago>();

            foreach (ListViewItem item in lswResago.Items)
            {
                Resago r = new Resago();

                r.Nombre = item.Text;
                r.Kilos = Validacion.ValDecimal(item.SubItems[1]);
                r.Preciokilo = Validacion.ValDecimal(item.SubItems[2]);
                r.Escontable = chkResagoEsContable.Checked ? "S" : "N";

                resagos.Add(r);
            }

            return resagos;
        }

        private List<Cheque> ArmarCheques()
        {
            List<Cheque> cheques = new List<Cheque>();

            foreach (ListViewItem item in lswCheque.Items)
            {
                Cheque c = new Cheque();
                
                c.Banco = item.Text;
                c.Nombre = item.SubItems[1].Text;
                c.Fechadeposito = Validacion.ValFecha(item.SubItems[2]);
                c.Importe = Validacion.ValDecimal(item.SubItems[3]);
                c.Escontable = chkChequeEsContable.Checked ? "S" : "N";

                cheques.Add(c);
            }

            return cheques;
        }

        private List<FacturaProducto> ArmarProductos()
        {
            List<FacturaProducto> prods = new List<FacturaProducto>();

            foreach (ListViewItem item in lswProducto.Items)
            {
                FacturaProducto p = new FacturaProducto();

                p.IDProducto = (int)item.Tag;
                p.Cantidad = Validacion.ValDecimal(item.SubItems[0]);
                p.Importeunitario = Validacion.ValDecimal(item.SubItems[4]);
                p.Pesounitario = Validacion.ValDecimal(item.SubItems[3]);
                p.Importetotal = Validacion.ValDecimal(item.SubItems[6]);
                p.Espreciomanoobra = item.SubItems[7].Text == "Si" ? "S" : "N";
                p.Datocontable = item.SubItems[8].Text == "Si" ? "S" : "N";
                p.Sumarensaldoresago = item.SubItems[9].Text == "Si" ? "S" : "N";      

                prods.Add(p);
            }

            return prods;
        }

        private bool ValidarFactura()
        {
            //numero
            if (Validacion.EstaVacio(txtNumeroFactura, "Debe ingresar el número de factura"))
                return false;

            //fecha
            if (Validacion.EstaVacio(txtFechaFactura, "Debe ingresar la fecha de la factura"))
                return false;

            //cliente
            if (Validacion.EstaVacio(cboCliente, "Debe ingresar el cliente"))
                return false;

            //al menos 1 producto ?
            if (Validacion.EstaVacio(lswProducto, txtCodigoProducto, "Debe ingresar al menos 1 producto"))
                return false;

            return true;
        }

        private void btnBuscarFactura_Click(object sender, EventArgs e)
        {
            Factura fac = new Factura();

            txtNumeroFactura.Text = String.Format("{0:00000000}", int.Parse(txtNumeroFactura.Text));

            fac = fac.BuscarPorNumero(txtNumeroFactura.Text);

            if (fac == null)
            {
                Validacion.MostrarMensaje("El número de factura no existe");
                return;
            }

            LimpiarEncabezado();
            LimpiarDetalle();

            FacturaProducto fp = new FacturaProducto();
            List<FacturaProducto> productos = fp.BuscarPorIDFactura(fac.ID);

            Cheque c = new Cheque();
            List<Cheque> cheques = c.BuscarPorIDFactura(fac.ID);

            Resago r = new Resago();
            List<Resago> resagos = r.BuscarPorIDFactura(fac.ID);

            CargarFactura(fac);
            CargarProductos(productos);
            CargarCheques(cheques);
            CargarResagos(resagos);

            CalcularTotales();

            btnGuardar.Enabled = false;
            btnImprimir.Enabled = true;
        }

        private void CargarFactura(Factura fac)
        {            
            this.Tag = fac.ID;
            txtFechaFactura.Text = fac.Fecha.ToShortDateString();
            txtCodigoCliente.Text = fac.Codigocliente;

            KeyPressEventArgs e = new KeyPressEventArgs((char)13);
            txtCodigoCliente_KeyPress(this, e);

            txtEfectivoEntregado.Text = fac.Importeentregado.ToString("0.00");
            txtPorcentajeBonificacion.Text = fac.Porcentajebonificacion.ToString("0.00");
            txtPorcentajeIVA.Text = fac.Porcentajeiva.ToString("0.00");
            txtSubtotal.Text = fac.Subtotal.ToString("0.00");

            txtSaldoAnterior.Text = fac.Saldoanterior.ToString("0.00");
            txtSaldoAnterior2.Text = fac.Saldoanterior2.ToString("0.00");

            txtResagosProductos.Text = fac.Totalresagosproductos.ToString("0.00");
            txtMermaPorcentaje.Text = fac.Mermaporcentaje.ToString("0.00");
            txtMermaKilos.Text = fac.Mermakilos.ToString("0.00");
            txtSaldoAnteriorKg.Text = fac.Saldofavorresagos.ToString("0.00");
            txtTotalResagos.Text = fac.Totalresagos.ToString("0.00");
            txtTotalKilosEntregado.Text = fac.Totalresagosentregados.ToString("0.00");
            txtNuevoSaldoKg.Text = fac.Saldonuevoresagos.ToString("0.00");

            chkEfectivoEsContable.Checked = fac.Efectivoescontable == "S" ? true : false;
        }

        private void CargarProductos(List<FacturaProducto> productos)
        {
            lswProducto.Items.Clear();
            foreach (var p in productos)
            {
                AgregarProducto(p.Codigoproducto, p.IDProducto, p.Producto, p.Cantidad, 
                    p.Espreciomanoobra, p.Importeunitario, p.Importetotal, p.Datocontable, p.Pesounitario, p.Sumarensaldoresago);
            }
        }

        private void CargarCheques(List<Cheque> cheques)
        {
            lswCheque.Items.Clear();
            foreach (var c in cheques)
            {
                AgregarCheque(c.Banco, c.Nombre, c.Fechadeposito.ToShortDateString(), c.Importe, c.Escontable == "S" ? true : false);
            }
        }

        private void CargarResagos(List<Resago> resagos)
        {
            lswResago.Items.Clear();
            foreach (var r in resagos)
            {
                AgregarResago(r.Nombre, r.Kilos, r.Preciokilo, r.Kilos * r.Preciokilo, r.Escontable == "S" ? true : false);
            }
        }

        private void txtCodigoProducto_TextChanged_1(object sender, EventArgs e)
        {

        }

        private void btnNueva_Click(object sender, EventArgs e)
        {
            if (Validacion.MostrarMensaje("Se perderán todos los datos que no se hayan guardado. ¿Desea continuar?", TipoMensaje.Pregunta) == DialogResult.No)
                return;

            cboCliente.SelectedIndex = 0;
            LimpiarEncabezado();
            LimpiarDetalle();

            btnGuardar.Enabled = true;
            btnImprimir.Enabled = false;
        }

        private void txtBuscarDescripcion_TextChanged(object sender, EventArgs e)
        {

        }

        private void txtBuscarDescripcion_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == (char)13)
            {
                Producto prod = new Producto();

                cboProducto.DataSource = null;
                LimpiarDetalle();

                if (txtBuscarDescripcion.Text == "")
                {
                    prod.CargarCombo(cboProducto, true);
                    return;
                }
                
                DataSet ds = prod.BuscarDataSetPorNombreDescripcion(txtBuscarDescripcion.Text);
                
                prod.CargarComboConDescripcion(cboProducto, ds);
                
                cboProducto.Focus();

                e.Handled = true;
            }
        }

        private void txtPrecioManoObra_TextChanged(object sender, EventArgs e)
        {
            cambioPrecio = true;
        }

        private void txtPrecio_TextChanged(object sender, EventArgs e)
        {
            cambioPrecio = true;
        }

        private void txtMermaPorcentaje_Leave(object sender, EventArgs e)
        {
            CalcularTotales();
        }

        private void txtMermaPorcentaje_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == (char)13)
                CalcularTotales();
        }
    }
}
